package com.fare.taluo.core.domain.crawl.adapter.sub;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

import com.fare.taluo.conf.ConfigContainer;
import com.fare.taluo.core.domain.ChannelConst;
import com.fare.taluo.core.domain.crawl.CrawlTaskModel;
import com.fare.taluo.core.domain.crawl.PageErrorResultException;
import com.fare.taluo.core.domain.crawl.adapter.AbstractAdapter;
import com.fare.taluo.core.domain.crawl.adapter.CrawlAdapterFactory;
import com.fare.taluo.core.domain.entity.crawl.FreightPriceEntity;
import com.fare.taluo.util.RegHtmlUtil;

/**
 * 东方航空官网http://www.ceair.com
 */

public class MUAirAdapter extends AbstractAdapter {

	protected DocumentBuilderFactory factory = DocumentBuilderFactory
			.newInstance();

	public MUAirAdapter(CrawlTaskModel taskModel) {
		super(taskModel);
	}

	@Override
	public List<Object> paraseToVo(Object fetchObject) throws Exception {
		List<Object> dataList = new ArrayList<Object>();
		String shtml = (String) fetchObject;
		String flightId = null;
		String filgType = null;
		String arrTime = null;
		String deptTime = null;
		String lowerPrice = null;
		String highPrice = null;
		List<String> list = getMlementContentReturn(shtml);
		if (list != null) {
			for (String s : list) {
				try {
					flightId = RegHtmlUtil
							.regStr(s,
									"<td><input type=\"radio\" checked=\"checked\" name=\"flight_radio\" value=\"(.*)&\\d+\" id=\"class_select\" style=\"display: none;\" />");
					filgType = RegHtmlUtil
							.regStr(s,
									"<span class=\"a_flightnumber\">(.{3,10})\\s*</span>");
					deptTime = RegHtmlUtil
							.regStr(s,
									"<td mark=\"order_time\">((\\d\\d):(\\d\\d))\\s*&rarr;\\s*((\\d\\d):(\\d\\d))\\s*<!--",
									1);
					arrTime = RegHtmlUtil
							.regStr(s,
									"<td mark=\"order_time\">((\\d\\d):(\\d\\d))\\s*&rarr;\\s*((\\d\\d):(\\d\\d))\\s*<!--",
									4);
					lowerPrice = RegHtmlUtil
							.regStr(s,
									"<input type='radio' name=\"segpay_memb_radio\" value=\"(\\d+\\.\\d+)&\\w+\" pricedisplay=\"\" />\\s*<span class=\"grey_words\">");
					highPrice = RegHtmlUtil
							.regStr(s,
									"<input type='radio' name=\"segpay_memb_radio\" value=\"(\\d+\\.\\d+)&\\w+\" pricedisplay=\"\" />\\s*<span class=\"redder_words\">");

					dataList.add(CrawlAdapterFactory.createPlaneInfo(taskModel,
							"MU", "东航", "中国东方航空", deptTime, arrTime, flightId,
							lowerPrice, null, highPrice, filgType));
				} catch (Exception e) {
					logger.error("东方航空正则表达式解析对象出错：" + e.getMessage());
				} finally {
					flightId = null;
					filgType = null;
					arrTime = null;
					deptTime = null;
					lowerPrice = null;
					highPrice = null;
				}
			}
		}

		return dataList;
	}

	/**
	 * 得到每一行的记录
	 * 
	 * @param shtml
	 * @return
	 * @throws IOException
	 */
	private List<String> getMlementContentReturn(String sHtml)
			throws IOException {
		return RegHtmlUtil
				.retrieveLinks(
						RegHtmlUtil
								.regStr(sHtml,
										"<tbody id=\"search\">\\s*(.*?)\\s*</tbody>\\s*</table>\\s*"
												+ "<table width=\"100%\" border=\"0\" cellspacing=\"1\" cellpadding=\"0\" class=\"weekline\">",
										1, Pattern.DOTALL),
						"<tr flightinfourl=(.*?)\\s*<img src=\"/mu/images/btn_view_price_all.gif\"",
						1, Pattern.CASE_INSENSITIVE + Pattern.DOTALL);// ok
	}

	@Override
	public String getUrl() {
		String tripType = "OW";
		// if (taskModel.getIsReturn()==1) {
		// tripType = "RT";
		// }
		String currentDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
		StringBuilder builder = new StringBuilder();
		builder.append(
				"http://www.ceair.com/mu/front/reservation/flight-search!doFlightSearch.shtml?")
				.append("cond.tripType=")
				.append(tripType)
				.append("&cond.depCode=")
				.append(taskModel.getFromCity())
				.append("&cond.depDate=")
				.append(taskModel.getFlightDate())
				.append("&cond.arrCode=")
				.append(taskModel.getToCity())
				.append("&cond.arrDate=")
				.append(currentDate)
				.append("&cond.cabinRank=ECONOMY&cond.adultNumber=1&cond.childNumber=0&cond.sortType=1&cond.isInternationalFlight=331&cond.region=CN");
		// System.out.println(builder);
		return builder.toString();
	}

	@Override
	public Object fetch(String url) throws Exception {
		String result = null;
		HttpClient client = null;
		HttpGet httpGet = null;
		HttpResponse response = null;
		HttpEntity entity = null;
		try {

			client = super.getHttpClient();
			httpGet = new HttpGet(getUrl());
			// httpGet.setHeader("Connection", "close");
			response = client.execute(httpGet);
			entity = response.getEntity();
			result = EntityUtils.toString(entity);

			return result;
		} finally {
			if (httpGet != null)
				httpGet.releaseConnection();
			if (entity != null)
				EntityUtils.consume(entity);
			client = null;
			httpGet = null;
			entity = null;
		}
	}

	@Override
	public boolean validateFetch(Object fetchObject) throws Exception {
		if (fetchObject == null) {
			return false;
		} else if (fetchObject instanceof String) {
			if (((String) fetchObject).length() < 5000) {
				throw new PageErrorResultException("抓取的数据不正确(长度少于5000)");
			}
			// 验证字符串里是否包含抓取的错误信息
			String result = RegHtmlUtil.regStr((String) fetchObject,
					this.getErrors());
			if (result != null) {
				throw new PageErrorResultException(result);
			}
		}
		return true;
	}

	private List<String> getErrors() {
		List<String> errors = new ArrayList<String>();
		errors.add("404 Not Found");
		errors.add("Error 404: Not Found");
		errors.add("Access Denied");
		errors.add("HTTP .+ 404");
		errors.add("<title>Error</title>");
		errors.add("<li class=\"active\">\\s*航班查询\\s*</li>");// 返回的是航班查询页面
		return errors;
	}

	public static void main(String[] arg) throws Exception {

		CrawlTaskModel taskModel = new CrawlTaskModel();
		taskModel.setGrabChannelId(ChannelConst.CHANNEL_MU);
		taskModel.setFromCity("CAN");
		taskModel.setFromCityName("广州");
		taskModel.setToCity("PEK");
		taskModel.setToCityName("北京");
		taskModel.setFlightDate("2013-05-28");

		// 抓取数据相关配置
		ConfigContainer.getInstance().register(
				"com.fare.taluo.core.domain.crawl.CrawlPropertiesLoader");
		MUAirAdapter c = new MUAirAdapter(taskModel);
		System.out.println("fetch......");
		Object obj = c.fetch(null);

		System.out.println("paraseToVo......");
		List<Object> results = c.paraseToVo(obj);
		for (Object o : results) {
			FreightPriceEntity p = (FreightPriceEntity) o;
			System.out.println(p.toString());
		}

		System.out.println("finish .......");
	}
}
